#include "Bundle.h"

using std::map;
using std::set;
using std::vector;

enum {
    // Keep them in sync with BUNDLE_MAGIC* in frameworks/base/core/java/android/os/BaseBundle.java.
    BUNDLE_MAGIC = 0x4C444E42,
    BUNDLE_MAGIC_NATIVE = 0x4C444E44,
};

namespace {

template <typename T>
bool getValue(const std::string& key, T* out, const map<std::string, T>& map)
{
    const auto& it = map.find(key);
    if (it == map.end())
        return false;
    *out = it->second;
    return true;
}

template <typename T>
T getValue(const map<std::string, T>& map, const std::string& key, const T defaultValue)
{
    const auto& it = map.find(key);
    if (it == map.end())
        return defaultValue;
    return it->second;
}

template <typename T>
std::vector<T> getVectorValue(const map<std::string, std::vector<T>>& map, const std::string& key)
{
    const auto& it = map.find(key);
    if (it == map.end())
        return std::vector<T>();
    return it->second;
}

template <typename T>
set<std::string> getKeys(const map<std::string, T>& map)
{
    if (map.empty())
        return set<std::string>();
    set<std::string> keys;
    for (const auto& key_value_pair : map) {
        keys.emplace(key_value_pair.first);
    }
    return keys;
}

} // namespace

//#include <stdio.h>
#ifndef ALOGE
#define ALOGE(...) // {printf(__VA_ARGS__); printf("\n");}
#endif

namespace android {

#define RETURN_IF_FAILED(calledOnce)                                     \
    {                                                                    \
        status_t returnStatus = calledOnce;                              \
        if (returnStatus) {                                              \
            ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
            return returnStatus;                                         \
        }                                                                \
    }

#define RETURN_IF_ENTRY_ERASED(map, key)                                 \
    {                                                                    \
        size_t num_erased = (map).erase(key);                            \
        if (num_erased) {                                                \
            ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
            return num_erased;                                           \
        }                                                                \
    }

Bundle::Bundle(Bundle&& bundle)
    : mByteMap(std::move(bundle.mByteMap))
    , mShortMap(std::move(bundle.mShortMap))
    , mIntMap(std::move(bundle.mIntMap))
    , mLongMap(std::move(bundle.mLongMap))
    , mFloatMap(std::move(bundle.mFloatMap))
    , mDoubleMap(std::move(bundle.mDoubleMap))
    , mStringMap(std::move(bundle.mStringMap))

    , mByteVectorMap(std::move(bundle.mByteVectorMap))
    , mShortVectorMap(std::move(bundle.mShortVectorMap))
    , mIntVectorMap(std::move(bundle.mIntVectorMap))
    , mLongVectorMap(std::move(bundle.mLongVectorMap))
    , mFloatVectorMap(std::move(bundle.mFloatVectorMap))
    , mDoubleVectorMap(std::move(bundle.mDoubleVectorMap))
    , mStringVectorMap(std::move(bundle.mStringVectorMap))
{
}

Bundle& Bundle::operator=(Bundle&& bundle)
{
    mByteMap = std::move(bundle.mByteMap);
    mShortMap = std::move(bundle.mShortMap);
    mIntMap = std::move(bundle.mIntMap);
    mLongMap = std::move(bundle.mLongMap);
    mFloatMap = std::move(bundle.mFloatMap);
    mDoubleMap = std::move(bundle.mDoubleMap);
    mStringMap = std::move(bundle.mStringMap);

    mByteVectorMap = std::move(bundle.mByteVectorMap);
    mShortVectorMap = std::move(bundle.mShortVectorMap);
    mIntVectorMap = std::move(bundle.mIntVectorMap);
    mLongVectorMap = std::move(bundle.mLongVectorMap);
    mFloatVectorMap = std::move(bundle.mFloatVectorMap);
    mDoubleVectorMap = std::move(bundle.mDoubleVectorMap);
    mStringVectorMap = std::move(bundle.mStringVectorMap);
    return *this;
}

status_t Bundle::writeToParcel(Parcel* parcel) const
{
    /*
     * Keep implementation in sync with writeToParcelInner() in
     * frameworks/base/core/java/android/os/BaseBundle.java.
     */

    // Special case for empty bundles.
    if (empty()) {
        RETURN_IF_FAILED(parcel->writeInt32(0));
        return NO_ERROR;
    }

    // 数据长度， MAGIC, 数据
    size_t length_pos = parcel->dataPosition();
    RETURN_IF_FAILED(parcel->writeInt32(1)); // dummy, will hold length
    RETURN_IF_FAILED(parcel->writeInt32(BUNDLE_MAGIC_NATIVE));

    size_t start_pos = parcel->dataPosition();
    RETURN_IF_FAILED(writeToParcelInner(parcel));
    size_t end_pos = parcel->dataPosition();

    // Backpatch length. This length value includes the length header.
    parcel->setDataPosition(length_pos);
    size_t length = end_pos - start_pos;
    if (length > (size_t)std::numeric_limits<int32_t>::max()) {
        ALOGE("Parcel length (%zu) too large to store in 32-bit signed int", length);
        return BAD_VALUE;
    }
    RETURN_IF_FAILED(parcel->writeInt32(static_cast<int32_t>(length)));
    parcel->setDataPosition(end_pos);
    return NO_ERROR;
}

status_t Bundle::readFromParcel(const Parcel* parcel)
{
    parcel->setDataPosition(0); // Important!!!!
    /*
     * Keep implementation in sync with readFromParcelInner() in
     * frameworks/base/core/java/android/os/BaseBundle.java.
     */
    int32_t length = parcel->readInt32();
    if (length < 0) {
        ALOGE("Bad length in parcel: %d", length);
        return UNEXPECTED_NULL;
    }

    return readFromParcelInner(parcel, static_cast<size_t>(length));
}

bool Bundle::empty() const
{
    return size() == 0u;
}

size_t Bundle::size() const
{
    return (mByteMap.size() + mShortMap.size() + mIntMap.size() + mLongMap.size() + mFloatMap.size() + mDoubleMap.size() + mStringMap.size() + mByteVectorMap.size() + mShortVectorMap.size() + mIntVectorMap.size() + mLongVectorMap.size() + mFloatVectorMap.size() + mDoubleVectorMap.size() + mStringVectorMap.size());
}

size_t Bundle::erase(const std::string& key)
{
    RETURN_IF_ENTRY_ERASED(mByteMap, key);
    RETURN_IF_ENTRY_ERASED(mShortMap, key);
    RETURN_IF_ENTRY_ERASED(mIntMap, key);
    RETURN_IF_ENTRY_ERASED(mLongMap, key);
    RETURN_IF_ENTRY_ERASED(mFloatMap, key);
    RETURN_IF_ENTRY_ERASED(mDoubleMap, key);
    RETURN_IF_ENTRY_ERASED(mStringMap, key);

    RETURN_IF_ENTRY_ERASED(mByteVectorMap, key);
    RETURN_IF_ENTRY_ERASED(mShortVectorMap, key);
    RETURN_IF_ENTRY_ERASED(mIntVectorMap, key);
    RETURN_IF_ENTRY_ERASED(mLongVectorMap, key);
    RETURN_IF_ENTRY_ERASED(mFloatVectorMap, key);
    RETURN_IF_ENTRY_ERASED(mDoubleVectorMap, key);
    return mStringVectorMap.erase(key);
}

size_t Bundle::erase(std::string&& key)
{
    std::string str(std::move(key));
    return erase(str);
}


// 设置相关 -------------------------------------------------------------------------------------------------

Bundle& Bundle::putInt8(const std::string& key, const int8_t value)
{
    erase(key);
    mByteMap[key] = value;
    return *this;
}

Bundle& Bundle::putInt16(const std::string& key, const int16_t value)
{
    erase(key);
    mShortMap[key] = value;
    return *this;
}

Bundle& Bundle::putInt32(const std::string& key, const int32_t value)
{
    erase(key);
    mIntMap[key] = value;
    return *this;
}

Bundle& Bundle::putInt64(const std::string& key, const int64_t value)
{
    erase(key);
    mLongMap[key] = value;
    return *this;
}

Bundle& Bundle::putFloat(const std::string& key, const float value)
{       
    erase(key);
    mFloatMap[key] = value;
    return *this;
}

Bundle& Bundle::putDouble(const std::string& key, const double value)
{
    erase(key);
    mDoubleMap[key] = value;
    return *this;
}

Bundle& Bundle::putString(const std::string& key, const std::string& value)
{
    erase(key);
    mStringMap[key] = value;
    return *this;
}

Bundle& Bundle::putInt8Vector(const std::string& key, const vector<int8_t>& value)
{
    erase(key);
    mByteVectorMap[key] = value;
    return *this;
}

Bundle& Bundle::putInt16Vector(const std::string& key, const vector<int16_t>& value)
{
    erase(key);
    mShortVectorMap[key] = value;
    return *this;
}

Bundle& Bundle::putInt32Vector(const std::string& key, const vector<int32_t>& value)
{
    erase(key);
    mIntVectorMap[key] = value;
    return *this;
}

Bundle& Bundle::putInt64Vector(const std::string& key, const vector<int64_t>& value)
{
    erase(key);
    mLongVectorMap[key] = value;
    return *this;
}

Bundle& Bundle::putFloatVector(const std::string& key, const vector<float>& value)
{
    erase(key);
    mFloatVectorMap[key] = value;
    return *this;
}

Bundle& Bundle::putDoubleVector(const std::string& key, const vector<double>& value)
{
    erase(key);
    mDoubleVectorMap[key] = value;
    return *this;
}

Bundle& Bundle::putStringVector(const std::string& key, const vector<std::string>& value)
{
    erase(key);
    mStringVectorMap[key] = value;
    return *this;
}

// 设置相关(右值版本1) ----------------------------------------------------------------------------------------

Bundle& Bundle::putInt8(std::string&& key, const int8_t value)
{
    erase(key);
    mByteMap[std::move(key)] = value;
    return *this;
}

Bundle& Bundle::putInt16(std::string&& key, const int16_t value)
{
    erase(key);
    mShortMap[std::move(key)] = value;
    return *this;
}

Bundle& Bundle::putInt32(std::string&& key, const int32_t value)
{
    erase(key);
    mIntMap[std::move(key)] = value;
    return *this;
}

Bundle& Bundle::putInt64(std::string&& key, const int64_t value)
{
    erase(key);
    mLongMap[std::move(key)] = value;
    return *this;
}

Bundle& Bundle::putFloat(std::string&& key, const float value)
{
    erase(key);
    mFloatMap[std::move(key)] = value;
    return *this;
}

Bundle& Bundle::putDouble(std::string&& key, const double value)
{
    erase(key);
    mDoubleMap[std::move(key)] = value;
    return *this;
}

Bundle& Bundle::putString(std::string&& key, const std::string& value)
{
    erase(key);
    mStringMap[std::move(key)] = value;
    return *this;
}

Bundle& Bundle::putInt8Vector(std::string&& key, const vector<int8_t>& value)
{
    erase(key);
    mByteVectorMap[std::move(key)] = value;
    return *this;
}

Bundle& Bundle::putInt16Vector(std::string&& key, const vector<int16_t>& value)
{
    erase(key);
    mShortVectorMap[std::move(key)] = value;
    return *this;
}

Bundle& Bundle::putInt32Vector(std::string&& key, const vector<int32_t>& value)
{
    erase(key);
    mIntVectorMap[std::move(key)] = value;
    return *this;
}

Bundle& Bundle::putInt64Vector(std::string&& key, const vector<int64_t>& value)
{
    erase(key);
    mLongVectorMap[std::move(key)] = value;
    return *this;
}

Bundle& Bundle::putFloatVector(std::string&& key, const vector<float>& value)
{
    erase(key);
    mFloatVectorMap[std::move(key)] = value;
    return *this;
}

Bundle& Bundle::putDoubleVector(std::string&& key, const vector<double>& value)
{
    erase(key);
    mDoubleVectorMap[std::move(key)] = value;
    return *this;
}

Bundle& Bundle::putStringVector(std::string&& key, const vector<std::string>& value)
{
    erase(key);
    mStringVectorMap[std::move(key)] = value;
    return *this;
}

// 设置相关(右值版本2) ----------------------------------------------------------------------------------------

Bundle& Bundle::putString(std::string&& key, std::string&& value)
{
    erase(key);
    mStringMap[std::move(key)] = std::move(value);
    return *this;
}

Bundle& Bundle::putInt8Vector(std::string&& key, vector<int8_t>&& value)
{
    erase(key);
    mByteVectorMap[std::move(key)] = std::move(value);
    return *this;
}

Bundle& Bundle::putInt16Vector(std::string&& key, vector<int16_t>&& value)
{
    erase(key);
    mShortVectorMap[std::move(key)] = std::move(value);
    return *this;
}

Bundle& Bundle::putInt32Vector(std::string&& key, vector<int32_t>&& value)
{
    erase(key);
    mIntVectorMap[std::move(key)] = std::move(value);
    return *this;
}

Bundle& Bundle::putInt64Vector(std::string&& key, vector<int64_t>&& value)
{
    erase(key);
    mLongVectorMap[std::move(key)] = std::move(value);
    return *this;
}

Bundle& Bundle::putFloatVector(std::string&& key, vector<float>&& value)
{
    erase(key);
    mFloatVectorMap[std::move(key)] = std::move(value);
    return *this;
}

Bundle& Bundle::putDoubleVector(std::string&& key, vector<double>&& value)
{
    erase(key);
    mDoubleVectorMap[std::move(key)] = std::move(value);
    return *this;
}

Bundle& Bundle::putStringVector(std::string&& key, vector<std::string>&& value)
{
    erase(key);
    mStringVectorMap[std::move(key)] = std::move(value);
    return *this;
}

// 设置相关(右值版本3) ----------------------------------------------------------------------------------------

Bundle& Bundle::putString(const std::string& key, std::string&& value)
{
    erase(key);
    mStringMap[key] = std::move(value);
    return *this;
}

Bundle& Bundle::putInt8Vector(const std::string& key, vector<int8_t>&& value)
{
    erase(key);
    mByteVectorMap[key] = std::move(value);
    return *this;
}

Bundle& Bundle::putInt16Vector(const std::string& key, vector<int16_t>&& value)
{
    erase(key);
    mShortVectorMap[key] = std::move(value);
    return *this;
}

Bundle& Bundle::putInt32Vector(const std::string& key, vector<int32_t>&& value)
{
    erase(key);
    mIntVectorMap[key] = std::move(value);
    return *this;
}

Bundle& Bundle::putInt64Vector(const std::string& key, vector<int64_t>&& value)
{
    erase(key);
    mLongVectorMap[key] = std::move(value);
    return *this;
}

Bundle& Bundle::putFloatVector(const std::string& key, vector<float>&& value)
{
    erase(key);
    mFloatVectorMap[key] = std::move(value);
    return *this;
}

Bundle& Bundle::putDoubleVector(const std::string& key, vector<double>&& value)
{
    erase(key);
    mDoubleVectorMap[key] = std::move(value);
    return *this;
}

Bundle& Bundle::putStringVector(const std::string& key, vector<std::string>&& value)
{
    erase(key);
    mStringVectorMap[key] = std::move(value);
    return *this;
}

// 获取相关 -------------------------------------------------------------------------------------------------

int8_t Bundle::getInt8(const std::string& key, int8_t defaultValue) const
{
    return getValue(mByteMap, key, defaultValue);
}

int16_t Bundle::getInt16(const std::string& key, int16_t defaultValue) const
{
    return getValue(mShortMap, key, defaultValue);
}

int32_t Bundle::getInt32(const std::string& key, int32_t defaultValue) const
{
    return getValue(mIntMap, key, defaultValue);
}

int64_t Bundle::getInt64(const std::string& key, int64_t defaultValue) const
{
    return getValue(mLongMap, key, defaultValue);
}

float Bundle::getFloat(const std::string& key, float defaultValue) const
{
    return getValue(mFloatMap, key, defaultValue);
}

double Bundle::getDouble(const std::string& key, double defaultValue) const
{
    return getValue(mDoubleMap, key, defaultValue);
}

std::string Bundle::getString(const std::string& key, const std::string& defaultValue) const
{
    const auto& it = mStringMap.find(key);
    if (it == mStringMap.end())
        return defaultValue;
    return it->second;
}

std::vector<int8_t> Bundle::getInt8Vector(const std::string& key) const
{
    return getVectorValue(mByteVectorMap, key);
}

std::vector<int16_t> Bundle::getInt16Vector(const std::string& key) const
{
    return getVectorValue(mShortVectorMap, key);
}

std::vector<int32_t> Bundle::getInt32Vector(const std::string& key) const
{
    return getVectorValue(mIntVectorMap, key);
}

std::vector<int64_t> Bundle::getInt64Vector(const std::string& key) const
{
    return getVectorValue(mLongVectorMap, key);
}

std::vector<float> Bundle::getFloatVector(const std::string& key) const
{
    return getVectorValue(mFloatVectorMap, key);
}

std::vector<double> Bundle::getDoubleVector(const std::string& key) const
{
    return getVectorValue(mDoubleVectorMap, key);
}

std::vector<std::string> Bundle::getStringVector(const std::string& key) const
{
    return getVectorValue(mStringVectorMap, key);
}

// 获取相关(右值版本) -----------------------------------------------------------------------------------------

int8_t Bundle::getInt8(std::string&& key, const int8_t defaultValue) const
{
    std::string str(std::move(key));
    return getValue(mByteMap, str, defaultValue);
}

int16_t Bundle::getInt16(std::string&& key, const int16_t defaultValue) const
{
    std::string str(std::move(key));
    return getValue(mShortMap, str, defaultValue);
}

int32_t Bundle::getInt32(std::string&& key, const int32_t defaultValue) const
{
    std::string str(std::move(key));
    return getValue(mIntMap, str, defaultValue);
}

int64_t Bundle::getInt64(std::string&& key, const int64_t defaultValue) const
{
    std::string str(std::move(key));
    return getValue(mLongMap, str, defaultValue);
}

float Bundle::getFloat(std::string&& key, const float defaultValue) const
{
    std::string str(std::move(key));
    return getValue(mFloatMap, str, defaultValue);
}

double Bundle::getDouble(std::string&& key, const double defaultValue) const
{
    std::string str(std::move(key));
    return getValue(mDoubleMap, str, defaultValue);
}

std::string Bundle::getString(std::string&& key, const std::string& defaultValue) const
{
    std::string str(std::move(key)); // move
    const auto& it = mStringMap.find(str);
    if (it == mStringMap.end())
        return defaultValue;
    return it->second;
}

std::string Bundle::getString(std::string&& key, std::string&& defaultValue) const
{
    std::string str(std::move(key)); // move
    const auto& it = mStringMap.find(str);
    if (it == mStringMap.end())
        return defaultValue;
    std::string v(std::move(defaultValue)); // move
    return it->second;
}

std::string Bundle::getString(const std::string& key, std::string&& defaultValue) const
{
    const auto& it = mStringMap.find(key);
    if (it == mStringMap.end())
        return defaultValue;
    std::string v(std::move(defaultValue)); // move
    return it->second;
}

std::vector<int8_t> Bundle::getInt8Vector(std::string&& key) const
{
    std::string str(std::move(key));
    return getVectorValue(mByteVectorMap, str);
}

std::vector<int16_t> Bundle::getInt16Vector(std::string&& key) const
{
    std::string str(std::move(key));
    return getVectorValue(mShortVectorMap, str);
}

std::vector<int32_t> Bundle::getInt32Vector(std::string&& key) const
{
    std::string str(std::move(key));
    return getVectorValue(mIntVectorMap, str);
}

std::vector<int64_t> Bundle::getInt64Vector(std::string&& key) const
{
    std::string str(std::move(key));
    return getVectorValue(mLongVectorMap, str);
}

std::vector<float> Bundle::getFloatVector(std::string&& key) const
{
    std::string str(std::move(key));
    return getVectorValue(mFloatVectorMap, str);
}

std::vector<double> Bundle::getDoubleVector(std::string&& key) const
{
    std::string str(std::move(key));
    return getVectorValue(mDoubleVectorMap, str);
}

std::vector<std::string> Bundle::getStringVector(std::string&& key) const
{
    std::string str(std::move(key));
    return getVectorValue(mStringVectorMap, str);
}

// 键相关 ---------------------------------------------------------------------------------------------------

set<std::string> Bundle::getInt8Keys() const
{
    return getKeys(mByteMap);
}

set<std::string> Bundle::getInt16Keys() const
{
    return getKeys(mShortMap);
}

set<std::string> Bundle::getInt32Keys() const
{
    return getKeys(mIntMap);
}

set<std::string> Bundle::getInt64Keys() const
{
    return getKeys(mLongMap);
}

set<std::string> Bundle::getFloatKeys() const
{
    return getKeys(mFloatMap);
}

set<std::string> Bundle::getDoubleKeys() const
{
    return getKeys(mDoubleMap);
}

set<std::string> Bundle::getStringKeys() const
{
    return getKeys(mStringMap);
}

set<std::string> Bundle::getInt8VectorKeys() const
{
    return getKeys(mByteVectorMap);
}

set<std::string> Bundle::getInt16VectorKeys() const
{
    return getKeys(mShortVectorMap);
}

set<std::string> Bundle::getInt32VectorKeys() const
{
    return getKeys(mIntVectorMap);
}

set<std::string> Bundle::getInt64VectorKeys() const
{
    return getKeys(mLongVectorMap);
}

set<std::string> Bundle::getFloatVectorKeys() const
{
    return getKeys(mFloatVectorMap);
}

set<std::string> Bundle::getDoubleVectorKeys() const
{
    return getKeys(mDoubleVectorMap);
}

set<std::string> Bundle::getStringVectorKeys() const
{
    return getKeys(mStringVectorMap);
}

// 序列化/反序列化相关 ----------------------------------------------------------------------------------------

status_t Bundle::writeToParcelInner(Parcel* parcel) const
{
    /*
     * To keep this implementation in sync with writeArrayMapInternal() in
     * frameworks/base/core/java/android/os/Parcel.java, the number of key
     * value pairs must be written into the parcel before writing the key-value
     * pairs themselves.
     */
    size_t num_entries = size();
    if (num_entries > (size_t)std::numeric_limits<int32_t>::max()) {
        ALOGE("The size of this Bundle (%zu) too large to store in 32-bit signed int",
            num_entries);
        return BAD_VALUE;
    }
    RETURN_IF_FAILED(parcel->writeInt32(static_cast<int32_t>(num_entries)));

    for (const auto& key_val_pair : mByteMap) {
        RETURN_IF_FAILED(parcel->writeString(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt8(VAL_BYTE));
        RETURN_IF_FAILED(parcel->writeInt8(key_val_pair.second));
    }
    for (const auto& key_val_pair : mShortMap) {
        RETURN_IF_FAILED(parcel->writeString(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt8(VAL_SHORT));
        RETURN_IF_FAILED(parcel->writeInt16(key_val_pair.second));
    }
    for (const auto& key_val_pair : mIntMap) {
        RETURN_IF_FAILED(parcel->writeString(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt8(VAL_INTEGER));
        RETURN_IF_FAILED(parcel->writeInt32(key_val_pair.second));
    }
    for (const auto& key_val_pair : mLongMap) {
        RETURN_IF_FAILED(parcel->writeString(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt8(VAL_LONG));
        RETURN_IF_FAILED(parcel->writeInt64(key_val_pair.second));
    }
    for (const auto& key_val_pair : mFloatMap) {
        RETURN_IF_FAILED(parcel->writeString(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt8(VAL_FLOAT));
        RETURN_IF_FAILED(parcel->writeFloat(key_val_pair.second));
    }
    for (const auto& key_val_pair : mDoubleMap) {
        RETURN_IF_FAILED(parcel->writeString(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt8(VAL_DOUBLE));
        RETURN_IF_FAILED(parcel->writeDouble(key_val_pair.second));
    }
    for (const auto& key_val_pair : mStringMap) {
        RETURN_IF_FAILED(parcel->writeString(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt8(VAL_STRING));
        RETURN_IF_FAILED(parcel->writeString(key_val_pair.second));
    }

    for (const auto& key_val_pair : mByteVectorMap) {
        RETURN_IF_FAILED(parcel->writeString(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt8(VAL_BYTEARRAY));
        RETURN_IF_FAILED(parcel->writeInt8Vector(key_val_pair.second));
    }
    for (const auto& key_val_pair : mShortVectorMap) {
        RETURN_IF_FAILED(parcel->writeString(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt8(VAL_SHORTARRAY));
        RETURN_IF_FAILED(parcel->writeInt16Vector(key_val_pair.second));
    }
    for (const auto& key_val_pair : mIntVectorMap) {
        RETURN_IF_FAILED(parcel->writeString(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt8(VAL_INTARRAY));
        RETURN_IF_FAILED(parcel->writeInt32Vector(key_val_pair.second));
    }
    for (const auto& key_val_pair : mLongVectorMap) {
        RETURN_IF_FAILED(parcel->writeString(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt8(VAL_LONGARRAY));
        RETURN_IF_FAILED(parcel->writeInt64Vector(key_val_pair.second));
    }
    for (const auto& key_val_pair : mFloatVectorMap) {
        RETURN_IF_FAILED(parcel->writeString(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt8(VAL_FLOATARRAY));
        RETURN_IF_FAILED(parcel->writeFloatVector(key_val_pair.second));
    }
    for (const auto& key_val_pair : mDoubleVectorMap) {
        RETURN_IF_FAILED(parcel->writeString(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt8(VAL_DOUBLEARRAY));
        RETURN_IF_FAILED(parcel->writeDoubleVector(key_val_pair.second));
    }
    for (const auto& key_val_pair : mStringVectorMap) {
        RETURN_IF_FAILED(parcel->writeString(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt8(VAL_STRINGARRAY));
        RETURN_IF_FAILED(parcel->writeStringVector(key_val_pair.second));
    }
    return NO_ERROR;
}

status_t Bundle::readFromParcelInner(const Parcel* parcel, size_t length)
{
    /*
     * Note: we don't actually use length for anything other than an empty Bundle
     * check, since we do not actually need to copy in an entire Parcel, unlike in the Java
     * implementation.
     */
    if (length == 0) {
        // Empty Bundle or end of data.
        return NO_ERROR;
    }

    int32_t magic;
    RETURN_IF_FAILED(parcel->readInt32(&magic));
    if (magic != BUNDLE_MAGIC && magic != BUNDLE_MAGIC_NATIVE) {
        ALOGE("Bad magic number for Bundle: 0x%08x", magic);
        return BAD_VALUE;
    }

    /*
     * To keep this implementation in sync with unparcel() in
     * frameworks/base/core/java/android/os/BaseBundle.java, the number of
     * key-value pairs must be read from the parcel before reading the key-value
     * pairs themselves.
     */
    int32_t num_entries;
    RETURN_IF_FAILED(parcel->readInt32(&num_entries));

    for (; num_entries > 0; --num_entries) {
        std::string key;
        int8_t value_type;
        RETURN_IF_FAILED(parcel->readString(&key));
        RETURN_IF_FAILED(parcel->readInt8(&value_type));

        /*
         * We assume that both the C++ and Java APIs ensure that all keys in a Bundle
         * are unique.
         */
        switch (value_type) {
        case VAL_BYTE: {
            RETURN_IF_FAILED(parcel->readInt8(&mByteMap[key]));
            break;
        }
        case VAL_SHORT: {
            RETURN_IF_FAILED(parcel->readInt16(&mShortMap[key]));
            break;
        }
        case VAL_INTEGER: {
            RETURN_IF_FAILED(parcel->readInt32(&mIntMap[key]));
            break;
        }
        case VAL_LONG: {
            RETURN_IF_FAILED(parcel->readInt64(&mLongMap[key]));
            break;
        }
        case VAL_FLOAT: {
            RETURN_IF_FAILED(parcel->readFloat(&mFloatMap[key]));
            break;
        }
        case VAL_DOUBLE: {
            RETURN_IF_FAILED(parcel->readDouble(&mDoubleMap[key]));
            break;
        }
        case VAL_STRING: {
            RETURN_IF_FAILED(parcel->readString(&mStringMap[key]));
            break;
        }

        case VAL_BYTEARRAY: {
            RETURN_IF_FAILED(parcel->readInt8Vector(&mByteVectorMap[key]));
            break;
        }
        case VAL_SHORTARRAY: {
            RETURN_IF_FAILED(parcel->readInt16Vector(&mShortVectorMap[key]));
            break;
        }
        case VAL_INTARRAY: {
            RETURN_IF_FAILED(parcel->readInt32Vector(&mIntVectorMap[key]));
            break;
        }
        case VAL_LONGARRAY: {
            RETURN_IF_FAILED(parcel->readInt64Vector(&mLongVectorMap[key]));
            break;
        }
        case VAL_FLOATARRAY: {
            RETURN_IF_FAILED(parcel->readFloatVector(&mFloatVectorMap[key]));
            break;
        }
        case VAL_DOUBLEARRAY: {
            RETURN_IF_FAILED(parcel->readDoubleVector(&mDoubleVectorMap[key]));
            break;
        }
        case VAL_STRINGARRAY: {
            RETURN_IF_FAILED(parcel->readStringVector(&mStringVectorMap[key]));
            break;
        }
        default: {
            ALOGE("Unrecognized type: %d", value_type);
            return BAD_TYPE;
            break;
        }
        }
    }

    return NO_ERROR;
}

} // namespace android
